package hos.http.converter;

import android.text.TextUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import hos.http.HttpConstant;
import hos.http.HttpException;
import hos.http.HttpLogUtils;
import hos.http.HttpRequest;
import hos.http.retrofit.TypeUtil;

/**
 * <p>Title: HttpConverterUtils </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2024-03-27 14:22
 */
public class HttpConverterUtils {
    public static Object requireData(HttpRequest<?> request, Type succeed, String json) throws HttpException {
        HttpLogUtils.responseLog(request, json);
        if (TypeUtil.equals(succeed, Integer.class)) {
            return Integer.valueOf(json);
        }
        if (TypeUtil.equals(succeed, Long.class)) {
            return Long.valueOf(json);
        }
        if (TypeUtil.equals(succeed, Float.class)) {
            return Float.valueOf(json);
        }
        if (TypeUtil.equals(succeed, Double.class)) {
            return Double.valueOf(json);
        }
        if (TypeUtil.equals(succeed, Boolean.class)) {
            return Boolean.valueOf(json);
        }
        if (TypeUtil.equals(succeed, String.class)) {
            return json;
        }
//        // 不是基本类型，开始判断结果泛型是不是 List<Map<String,?>> 或者 Map<String,?>
//        Class<?> rawType = Utils.getRawType(succeed);
//        if (Utils.equals(rawType, List.class)) {
//            Type parameterUpperBound = Utils.getParameterUpperBound(0, (ParameterizedType) succeed);
//            Class<?> rawTypeParameterUpperBound = Utils.getRawType(parameterUpperBound);
//            if (Utils.equals(rawTypeParameterUpperBound, Map.class)) {
//                Type parameterUpperBoundMap = Utils.getParameterUpperBound(0, (ParameterizedType) parameterUpperBound);
//                Class<?> rawTypeParameterUpperBoundMap = Utils.getRawType(parameterUpperBoundMap);
//                if (Utils.equals(rawTypeParameterUpperBoundMap, String.class)) {
//                    // List<Map<String,?>>
//                    return HttpConverterUtils.parse(request.getUrl(), json);
//                }
//            }
//        } else if (Utils.equals(rawType, Map.class)) {
//            Type parameterUpperBound = Utils.getParameterUpperBound(0, (ParameterizedType) succeed);
//            Class<?> rawTypeParameterUpperBound = Utils.getRawType(parameterUpperBound);
//            if (Utils.equals(rawTypeParameterUpperBound, String.class)) {
//                // Map<String,?>
//                return HttpConverterUtils.parse(request.getUrl(), json);
//            }
//        }
        throw HttpException.throwConverter(request.getUrl());
    }


    public static Object parse(String url, String json) throws HttpException {
        try {
            if (json.startsWith("{") && json.endsWith("}")) {
                return parseMap(json);
            } else {
                return parseList(json);
            }
        } catch (JSONException e) {
            throw HttpException.throwConverter(url, e);
        }
    }

    public static Map<String, Object> parseMap(String json) throws JSONException {
        return parseJsonObject(new JSONObject(json));
    }

    public static List<Map<String, Object>> parseList(String json) throws JSONException {
        return parseJsonArray(new JSONArray(json));
    }

    public static Map<String, Object> parseJsonObject(JSONObject json) {
        Map<String, Object> map = new HashMap<String, Object>();
        Iterator<String> rootKey = json.keys();
        //迭代是反复内容,使用循环实现,循环的条件,集合中没元素, hasNext()返回了false
        while (rootKey.hasNext()) {
            String key = rootKey.next();
            try {
                Object value = json.get(key);
                if (value instanceof JSONObject) {
                    map.put(key, parseJsonObject((JSONObject) value));
                } else if (value instanceof JSONArray) {
                    map.put(key, parseJsonArray((JSONArray) value));
                } else {
                    map.put(key, value);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    public static List<Map<String, Object>> parseJsonArray(JSONArray json) {
        List<Map<String, Object>> list = new ArrayList<>();
        int length = json.length();
        for (int i = 0; i < length; i++) {
            try {
                Object value = json.get(i);
                if (value instanceof JSONObject) {
                    list.add(parseJsonObject((JSONObject) value));
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    public static String requireJson(
            String url, String jsonResponse, String success
    ) throws HttpException {
        return requireJson(url, jsonResponse, success, "code", "msg");
    }

    public static String requireJson(
            String url, String jsonResponse, String success, String code
    ) throws HttpException {
        return requireJson(url, jsonResponse, success, code, "msg");
    }

    public static String requireJson(
            String url, String jsonResponse
    ) throws HttpException {
        return requireJson(url, jsonResponse, "200", "code", "msg");
    }

    public static String requireJson(
            String url, String jsonResponse,
            String success, String code, String message
    ) throws HttpException {
        if (jsonResponse == null) {
            throw HttpException.throwResultNull(url);
        }
        try {
            JSONObject json = new JSONObject(jsonResponse); // 获取JSON中后端定义的错误码和错误信息
            String srvCode = json.getString(code);
            if (TextUtils.equals(srvCode, success)) { // 对比后端自定义错误码
                return jsonResponse;
            } else { // 错误码匹配失败, 开始写入错误异常
                String errorMessage = json.optString(message, HttpConstant.SERVER_ERROR);
                // 将业务错误码作为tag传递
                throw HttpException.throwResult(url, errorMessage);
            }
        } catch (JSONException e) { // 固定格式JSON分析失败直接解析JSON
            throw HttpException.throwConverter(url, e);
        }
    }

    public static String requireJsonData(
            String url, String jsonResponse
    ) throws HttpException {
        return requireJsonData(url, jsonResponse, "200", "code", "msg", "data");
    }

    public static String requireJsonData(
            String url, String jsonResponse,
            String success
    ) throws HttpException {
        return requireJsonData(url, jsonResponse, success, "code", "msg", "data");
    }

    public static String requireJsonData(
            String url, String jsonResponse,
            String success, String code
    ) throws HttpException {
        return requireJsonData(url, jsonResponse, success, code, "msg", "data");
    }

    public static String requireJsonData(
            String url, String jsonResponse,
            String success, String code, String message
    ) throws HttpException {
        return requireJsonData(url, jsonResponse, success, code, message, "data");
    }

    public static String requireJsonData(
            String url, String jsonResponse,
            String success, String code, String message,
            String data
    ) throws HttpException {
        if (jsonResponse == null) {
            throw HttpException.throwResultNull(url);
        }
        try {
            JSONObject json = new JSONObject(jsonResponse); // 获取JSON中后端定义的错误码和错误信息
            String srvCode = json.getString(code);
            if (TextUtils.equals(srvCode, success)) { // 对比后端自定义错误码
                return json.optString(data);
            } else { // 错误码匹配失败, 开始写入错误异常
                String errorMessage = json.optString(message, HttpConstant.SERVER_ERROR);
                // 将业务错误码作为tag传递
                throw HttpException.throwResult(url, errorMessage);
            }
        } catch (JSONException e) { // 固定格式JSON分析失败直接解析JSON
            throw HttpException.throwConverter(url, e);
        }
    }
}
